package triseries;

import java.io.IOException;
import java.io.Serializable;
import java.nio.file.FileSystem;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Date;
import java.util.Set;

import com.kokotchy.betaSeriesAPI.HashCodeUtil;
import com.kokotchy.betaSeriesAPI.model.Episode;
import com.kokotchy.betaSeriesAPI.model.Subtitle;
import com.kokotchy.betaSeriesAPI.model.SubtitleLanguage;

import fr.toto.subtitles.Download;
import fr.toto.subtitles.SoutitreSet;
import fr.toto.triseries.BetaSeriesQuery;
import fr.toto.triseries.EpisodesSet;
import fr.toto.triseries.Regex;

public class Soutitre implements Serializable, Runnable {

	/**
	 * 
	 */
	private static final long serialVersionUID = 6033944077390241678L;
	private String url;
	private int season;
	private int episode;
	private String lang;
	private String file;
	private static boolean DEBUG = true;

	public Soutitre(Episode ep, String lang, String file) {
		url = ep.getShowUrl();
		season = ep.getSeason();
		episode = ep.getEpisode();
		this.lang = lang;
		this.file = file;
	}

	public String toString() {
		return url + " - " + season + "x" + episode + " - " + lang;
	}

	@Override
	public int hashCode() {
		int result = HashCodeUtil.SEED;
		result = HashCodeUtil.hash(result, url);
		result = HashCodeUtil.hash(result, season);
		result = HashCodeUtil.hash(result, episode);
		result = HashCodeUtil.hash(result, lang);
		return result;
	}

	public boolean equals(Soutitre s) {
		return (this.url.equals(s.url)) && (this.season == s.season)
				&& (this.episode == s.episode) && (this.lang.equals(s.lang));

	}

	public void run() {
		if (DEBUG)
			System.out.println("Recherche Sous-titre de : " + url + " "
					+ season + "x" + episode + " " + lang);
		Episode ep = EpisodesSet.find(url, season, episode);
		if (ep == null) {
			ep = BetaSeriesQuery.getEpisode(url, season, episode);
			if (ep == null) {
				SoutitreSet.add(this.copy());
				SoutitreSet.Save();
				return;
			}
			EpisodesSet.add(ep);
		}
		getSubtitle(ep);
	}

	public void getSubtitle(Episode ep) {
		if (DEBUG)
			System.out.println("Recherche Sous-titre " + lang + " de : "
					+ ep.toString());
		try {
			Subtitle sub = Regex.getBestSubtitle(ep.getSubtitles(), file, SubtitleLanguage.valueOf(lang) ,
					episode, season);
			if (sub == null) {
				if (DEBUG)
					System.out.println("Rien trouvé...");
				Long l = (new Date().getTime()) / 1000 - ep.getDate();
				if (l > 16200000) {
					Set<Subtitle> subs = BetaSeriesQuery.getSubtitle(url,
							season, episode, SubtitleLanguage.valueOf(lang));
					sub = Regex.getBestSubtitle(subs, file, SubtitleLanguage.valueOf(lang), episode,
							season);
					if (sub == null) {
						SoutitreSet.remove(this.copy());
						return;
					}

				} else
					throw new Exception();
			}

			if (sub.getContent().iterator().next() == null) {
				// traitement pour un fichier soustitre non zippé
				if (DEBUG)
					System.out.println("Sous-titre sélectionné : "
							+ sub.getFile());
				String ext = sub.getFile().substring(
						sub.getFile().lastIndexOf("."), sub.getFile().length());

				Path subfile = Paths.get(Regex.getEpisodeDest(ep).toString()
						+ "." + lang + ext);

				if (Files.exists(subfile)) {
					System.err
							.println("Le soutitre existe déjà dans le dossier cible - Abandon");
					SoutitreSet.remove(this.copy());
					return;
				}

				Download.downloadfile(sub.getUrl(), subfile.toString());

				if (DEBUG)
					System.out.println("ajout de : " + subfile.toString());
			} else {

				if (DEBUG)
					System.out.println("Sous-titre sélectionné : "
							+ sub.getContent().iterator().next());

				String subInZip = sub.getContent().iterator().next();

				Path zipfile = Paths.get(Regex.getEpisodeDest(ep).getParent()
						.toString(), sub.getFile());

				String ext = subInZip.substring(subInZip.lastIndexOf("."),
						subInZip.length());

				Path subfile = Paths.get(Regex.getEpisodeDest(ep).toString()
						+ "." + lang + ext);

				if (Files.exists(subfile)) {
					System.err
							.println("Le soutitre existe déjà dans le dossier cible - Abandon");
					SoutitreSet.remove(this.copy());
					return;
				}

				// Téléchargement du ZIP
				Download.downloadfile(sub.getUrl(), zipfile.toString());

				// Système de fichiers ZIP
				FileSystem zipFS = FileSystems.newFileSystem(zipfile, null);

				// Copie de l'archive ZIP vers le disque dur
				Files.copy(zipFS.getPath(subInZip), subfile);

				if (DEBUG)
					System.out.println("ajout de : " + subfile.toString());

				// supression du zip téléchargé
				Files.delete(zipfile);

				zipFS.close();

			}

			SoutitreSet.remove(this.copy());

		} catch (Exception e) {
			SoutitreSet.add(this.copy());
		} finally {
			SoutitreSet.Save();
		}

	}

	public String getUrl() {
		// TODO Auto-generated method stub
		return String.format("%s/s%02de%02d", url, season, episode);
	}

	public boolean equals(String url2, int se, int ep, String lang2) {
		if (url.equalsIgnoreCase(url2) && se == season && ep == episode
				&& lang.equalsIgnoreCase(lang2))
			return true;
		return false;
	}

	public void move(Path file, Episode ep) throws IOException {

			String ext = file.toString().substring(
					file.toString().lastIndexOf("."), file.toString().length());

			Path subfile = Paths.get(Regex.getEpisodeDest(ep).toString() + "."
					+ lang + ext);

			if (Files.exists(subfile)) {
				Files.delete(subfile);
			}
			
			if (!Files.exists(subfile.getParent())) {
				Files.createDirectories(subfile.getParent());
			}

			Files.move(file, subfile);

			if (DEBUG)
				System.out.println("ajout de : " + subfile.toString());

	}
	
	public fr.toto.subtitles.Soutitre copy() {
		fr.toto.subtitles.Soutitre sub = new fr.toto.subtitles.Soutitre(url, season, episode, SubtitleLanguage.valueOf(lang),  file);
		return sub;
		
	}

}
